package com.game.majiang.Event.Time;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.game.majiang.config.LogManager;

import lombok.extern.log4j.Log4j;

@Log4j
public class TimeManager {
	public TimeManager()
	{
		InitTimer();
	}
	private HashMap<Integer, TimeListener> listeners = null;
	private HashMap<Integer, TimeListener> addlisteners = null;
	private HashMap<Integer, TimeListener> removelisteners = null;
	ScheduledExecutorService executorService = null;
	private int tick = 0;
	public void InitTimer()
	{
		executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
            	try {
        			addnotifyListeners();
        			removenotifyListeners();
        			if(tick >= 10)
        			{
        				tick = 0;
            			fireOnesecond();
        			}
        			tick++;
				} catch (Exception e) {
					log.error(e);
					StringWriter errors = new StringWriter();  
					e.printStackTrace(new PrintWriter(errors));  
					log.error(" exception:"+e.getMessage()+"\t"+errors.toString()+"    ......."); 
				}
            }
        }, 0, 100, TimeUnit.MILLISECONDS);
	}
	public void CloseTimer()
	{
        try {
			if(executorService != null)
			{
	            executorService.shutdown();
				if(!executorService.awaitTermination(1000, TimeUnit.MILLISECONDS)){  
					executorService.shutdownNow();  
		            executorService = null;
					LogManager.getInstance().Log("@@@@@@@@@@@@@@@删删删");
				}
			}
		} catch (InterruptedException e) {
			LogManager.getInstance().Log("#######################删删删");
			// TODO Auto-generated catch block
			executorService.shutdownNow();  
            executorService = null;
		}  
	}
	public synchronized void addTimeListener(TimeListener listener) {
		  if (addlisteners == null) {
			  addlisteners = new HashMap<Integer, TimeListener>();
		  }
		  addlisteners.put(listener.hashCode(), listener);
		 }
	public synchronized void removeDoorListener(TimeListener listener) {
		if (removelisteners == null) {
			removelisteners = new HashMap<Integer, TimeListener>();
		  }
		  removelisteners.put(listener.hashCode(), listener);
		 }
	protected void fireOnesecond() {
		  if (listeners == null)
		   return;
		  TimeEvent event = new TimeEvent(this);
		  notifyListeners(event);
		 }
	private synchronized void addnotifyListeners() {
		if (listeners == null) {
			listeners = new HashMap<Integer, TimeListener>();
		  }
		if (addlisteners == null)
			   return;
		  Iterator<Map.Entry<Integer, TimeListener>> additer = addlisteners.entrySet().iterator();
		  while (additer.hasNext()) 
		  {
			  Map.Entry<Integer, TimeListener> listener = additer.next();
			  if(listener != null)
				  listeners.put(listener.getKey(), listener.getValue());
		  }
		  addlisteners.clear();
		 }
	private synchronized void removenotifyListeners() {
		if (removelisteners == null)
			   return;
		  Iterator<Map.Entry<Integer, TimeListener>> removeiter = removelisteners.entrySet().iterator();
		  while (removeiter.hasNext()) 
		  {
			  Map.Entry<Integer, TimeListener> listener = removeiter.next();
			  if(listener != null)
				  listeners.remove(listener.getKey());
		  }
		  removelisteners.clear();
		 }
	private void notifyListeners(TimeEvent event) {
		if (listeners == null)
			   return;
		  Iterator<Map.Entry<Integer, TimeListener>> iter = listeners.entrySet().iterator();
		  while (iter.hasNext()) 
		  {
			  Map.Entry<Integer, TimeListener> listener = iter.next();
			  if(listener != null)
			  {
				  try {
					  listener.getValue().timeEvent(event);					
				} catch (Exception e) {
					// TODO: handle exception
					log.error(e);
					StringWriter errors = new StringWriter();  
					e.printStackTrace(new PrintWriter(errors));  
					log.error(" exception:"+e.getMessage()+"\t"+errors.toString()+"    ......."); 
				}
			  }
		  }
		 }
}
